#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <vector>
#include <string>
#include <algorithm>
#include <iostream>
#include <thread>
#include <chrono>
#include <memory>
#include <windows.h>
#include <commctrl.h>
#pragma comment(lib, "comctl32.lib")

// MSF_GIF在所有必要依赖之后包含
#define MSF_GIF_IMPL
#include "msf_gif.h"

// 翻转RGBA图像数据（原点从左下角转为左上角）
void flipImageVertically(std::vector<uint8_t> &rgbaData, int width, int height, bool flip = true)
{
    if (!flip || width <= 0 || height <= 0)
        return;

    int rowSize = width * 4;
    for (int y = 0; y < height / 2; ++y)
    {
        int topRow = y;
        int bottomRow = height - 1 - y;
        std::swap_ranges(
            rgbaData.begin() + topRow * rowSize,
            rgbaData.begin() + (topRow + 1) * rowSize,
            rgbaData.begin() + bottomRow * rowSize);
    }
}

// 平台抽象层
class Platform
{
public:
    virtual ~Platform() = default;
    virtual bool getScreenSize(int &width, int &height) = 0;
    virtual bool selectRegionByPoints(int &startX, int &startY, int &endX, int &endY) = 0;
    virtual bool captureScreen(int x, int y, int width, int height, std::vector<uint8_t> &rgbaData) = 0;
    static Platform *create();
};

// Windows平台实现
class WindowsPlatform : public Platform
{
private:
    // 捕获整个屏幕（用于区域选择窗口背景）
    bool captureFullScreen(std::vector<uint8_t> &rgbaData, int &width, int &height)
    {
        // 获取屏幕尺寸（考虑DPI）
        HDC hdc = GetDC(NULL);
        width = GetDeviceCaps(hdc, HORZRES);
        height = GetDeviceCaps(hdc, VERTRES);
        ReleaseDC(NULL, hdc);

        // 获取屏幕DC
        HDC hdcScreen = GetDC(NULL);
        if (!hdcScreen)
        {
            std::cerr << "获取屏幕DC失败!" << std::endl;
            return false;
        }

        // 创建兼容DC和位图
        HDC hdcMemDC = CreateCompatibleDC(hdcScreen);
        HBITMAP hBitmap = CreateCompatibleBitmap(hdcScreen, width, height);
        if (!hBitmap)
        {
            std::cerr << "创建位图失败!" << std::endl;
            ReleaseDC(NULL, hdcScreen);
            DeleteDC(hdcMemDC);
            return false;
        }

        // 选择位图
        HBITMAP hOldBitmap = (HBITMAP)SelectObject(hdcMemDC, hBitmap);

        // 复制屏幕内容到位图
        BitBlt(hdcMemDC, 0, 0, width, height, hdcScreen, 0, 0, SRCCOPY);

        // 获取位图信息
        BITMAPINFO bmi = {0};
        bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
        bmi.bmiHeader.biWidth = width;
        bmi.bmiHeader.biHeight = height; // 保持正数，后续手动翻转
        bmi.bmiHeader.biPlanes = 1;
        bmi.bmiHeader.biBitCount = 32;
        bmi.bmiHeader.biCompression = BI_RGB;

        // 分配内存存储位图数据
        rgbaData.resize(width * height * 4);

        // 获取位图数据并翻转（确保显示正确）
        GetDIBits(hdcMemDC, hBitmap, 0, height, rgbaData.data(), &bmi, DIB_RGB_COLORS);
        flipImageVertically(rgbaData, width, height);

        // 清理资源
        SelectObject(hdcMemDC, hOldBitmap);
        DeleteObject(hBitmap);
        DeleteDC(hdcMemDC);
        ReleaseDC(NULL, hdcScreen);

        return true;
    }

    // 屏幕选择窗口过程
    static LRESULT CALLBACK PointSelectionWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
        static struct
        {
            bool firstPointSelected = false;
            bool secondPointSelected = false;
            POINT firstPoint = {0, 0};
            POINT secondPoint = {0, 0};
            bool regionSelected = false;
            int *pStartX = nullptr;
            int *pStartY = nullptr;
            int *pEndX = nullptr;
            int *pEndY = nullptr;
            HBITMAP hScreenBitmap = nullptr;
            int screenWidth = 0;
            int screenHeight = 0;
            HWND hCoordLabel = nullptr;
        } state;

        switch (msg)
        {
        case WM_CREATE:
        {
            CREATESTRUCT *cs = (CREATESTRUCT *)lParam;
            void **params = (void **)cs->lpCreateParams;
            state.pStartX = (int *)params[0];
            state.pStartY = (int *)params[1];
            state.pEndX = (int *)params[2];
            state.pEndY = (int *)params[3];
            state.hScreenBitmap = (HBITMAP)params[4];
            state.screenWidth = *(int *)params[5];
            state.screenHeight = *(int *)params[6];

            // 创建坐标显示标签
            state.hCoordLabel = CreateWindowEx(
                0, "Static", "点击屏幕选择第一个点 (红色)",
                WS_CHILD | WS_VISIBLE | SS_LEFT,
                10, 10, 400, 20,
                hwnd, (HMENU)1, GetModuleHandle(NULL), NULL);
            SetWindowLongPtr(state.hCoordLabel, GWL_EXSTYLE,
                             GetWindowLongPtr(state.hCoordLabel, GWL_EXSTYLE) | WS_EX_CLIENTEDGE);
            break;
        }

        case WM_LBUTTONDOWN:
        {
            int x = LOWORD(lParam);
            int y = HIWORD(lParam);

            if (!state.firstPointSelected)
            {
                state.firstPoint = {x, y};
                state.firstPointSelected = true;
                char text[100];
                sprintf_s(text, "第一个点: (%d, %d) - 点击选择第二个点 (蓝色)", x, y);
                SetWindowText(state.hCoordLabel, text);
            }
            else if (!state.secondPointSelected)
            {
                state.secondPoint = {x, y};
                state.secondPointSelected = true;
                char text[100];
                sprintf_s(text, "第一个点: (%d, %d)  第二个点: (%d, %d) - 按回车确认，按ESC取消",
                          state.firstPoint.x, state.firstPoint.y, x, y);
                SetWindowText(state.hCoordLabel, text);
            }
            InvalidateRect(hwnd, NULL, TRUE);
            break;
        }

        case WM_KEYDOWN:
            if (wParam == VK_RETURN && state.firstPointSelected && state.secondPointSelected)
            {
                // 计算标准化坐标
                *state.pStartX = std::min(state.firstPoint.x, state.secondPoint.x);
                *state.pStartY = std::min(state.firstPoint.y, state.secondPoint.y);
                *state.pEndX = std::max(state.firstPoint.x, state.secondPoint.x);
                *state.pEndY = std::max(state.firstPoint.y, state.secondPoint.y);
                state.regionSelected = true;

                // 确保在PostQuitMessage中传递正确的返回值
                PostQuitMessage(1); // 1表示成功选择
                return 0;
            }
            else if (wParam == VK_ESCAPE)
            {
                state.regionSelected = false;
                PostQuitMessage(0); // 0表示取消选择
                return 0;
            }
            break;
        case WM_PAINT:
        {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hwnd, &ps);

            // 绘制屏幕背景
            HDC hdcMem = CreateCompatibleDC(hdc);
            HBITMAP hOldBitmap = (HBITMAP)SelectObject(hdcMem, state.hScreenBitmap);
            BitBlt(hdc, 0, 0, state.screenWidth, state.screenHeight, hdcMem, 0, 0, SRCCOPY);
            SelectObject(hdcMem, hOldBitmap);
            DeleteDC(hdcMem);

            // 绘制第一个点（红色）
            if (state.firstPointSelected)
            {
                HPEN hPen = CreatePen(PS_SOLID, 2, RGB(255, 0, 0));
                HPEN hOldPen = (HPEN)SelectObject(hdc, hPen);
                // 十字线
                MoveToEx(hdc, state.firstPoint.x - 10, state.firstPoint.y, NULL);
                LineTo(hdc, state.firstPoint.x + 10, state.firstPoint.y);
                MoveToEx(hdc, state.firstPoint.x, state.firstPoint.y - 10, NULL);
                LineTo(hdc, state.firstPoint.x, state.firstPoint.y + 10);
                // 坐标文本
                char text[50];
                sprintf_s(text, "(%d, %d)", state.firstPoint.x, state.firstPoint.y);
                SetTextColor(hdc, RGB(255, 0, 0));
                TextOut(hdc, state.firstPoint.x + 15, state.firstPoint.y + 5, text, strlen(text));
                SelectObject(hdc, hOldPen);
                DeleteObject(hPen);
            }

            // 绘制第二个点（蓝色）和选择区域
            if (state.secondPointSelected && state.firstPointSelected)
            {
                HPEN hPen = CreatePen(PS_SOLID, 2, RGB(0, 0, 255));
                HPEN hOldPen = (HPEN)SelectObject(hdc, hPen);
                // 十字线
                MoveToEx(hdc, state.secondPoint.x - 10, state.secondPoint.y, NULL);
                LineTo(hdc, state.secondPoint.x + 10, state.secondPoint.y);
                MoveToEx(hdc, state.secondPoint.x, state.secondPoint.y - 10, NULL);
                LineTo(hdc, state.secondPoint.x, state.secondPoint.y + 10);
                // 坐标文本
                char text[50];
                sprintf_s(text, "(%d, %d)", state.secondPoint.x, state.secondPoint.y);
                SetTextColor(hdc, RGB(0, 0, 255));
                TextOut(hdc, state.secondPoint.x + 15, state.secondPoint.y + 5, text, strlen(text));
                SelectObject(hdc, hOldPen);
                DeleteObject(hPen);

                // 绘制选择区域（绿色虚线）
                int x1 = *state.pStartX;
                int y1 = *state.pStartY;
                int x2 = *state.pEndX;
                int y2 = *state.pEndY;
                HPEN hRectPen = CreatePen(PS_DASH, 1, RGB(0, 255, 0));
                HPEN hOldRectPen = (HPEN)SelectObject(hdc, hRectPen);
                Rectangle(hdc, x1, y1, x2, y2);
                // 区域尺寸文本
                char sizeText[64];
                sprintf_s(sizeText, "区域: %dx%d", x2 - x1, y2 - y1);
                SetTextColor(hdc, RGB(0, 255, 0));
                TextOut(hdc, x1 + 10, y1 + 10, sizeText, strlen(sizeText));
                SelectObject(hdc, hOldRectPen);
                DeleteObject(hRectPen);
            }

            EndPaint(hwnd, &ps);
            break;
        }

            // case WM_CLOSE:
            //     DestroyWindow(hwnd);
            //     break;

            // case WM_DESTROY:
            //     PostQuitMessage(state.regionSelected ? 1 : 0);
            //     break;

        default:
            return DefWindowProc(hwnd, msg, wParam, lParam);
        }
        return 0;
    }

public:
    bool getScreenSize(int &width, int &height) override
    {
        HDC hdc = GetDC(NULL);
        width = GetDeviceCaps(hdc, HORZRES); // 使用HORZRES/VERTRES获取真实分辨率（考虑DPI）
        height = GetDeviceCaps(hdc, VERTRES);
        ReleaseDC(NULL, hdc);
        return width > 0 && height > 0;
    }

    bool selectRegionByPoints(int &startX, int &startY, int &endX, int &endY) override
    {
        std::cout << "请在屏幕上选择录制区域..." << std::endl;
        std::cout << "操作提示: 点击两次选择区域，按Enter确认，按ESC取消" << std::endl;

        // 捕获全屏作为选择窗口背景
        std::vector<uint8_t> screenData;
        int screenWidth, screenHeight;
        if (!captureFullScreen(screenData, screenWidth, screenHeight))
        {
            std::cerr << "无法捕获屏幕内容!" << std::endl;
            return false;
        }

        // 创建屏幕位图
        HDC hdc = GetDC(NULL);
        HBITMAP hScreenBitmap = CreateBitmap(screenWidth, screenHeight, 1, 32, screenData.data());
        ReleaseDC(NULL, hdc);
        if (!hScreenBitmap)
        {
            std::cerr << "无法创建屏幕位图!" << std::endl;
            return false;
        }

        // 注册窗口类
        WNDCLASSEX wc = {0};
        wc.cbSize = sizeof(WNDCLASSEX);
        wc.lpfnWndProc = PointSelectionWindowProc;
        wc.hInstance = GetModuleHandle(NULL);
        wc.lpszClassName = "PointSelectionClass";
        wc.hCursor = LoadCursor(NULL, IDC_CROSS);
        wc.style = CS_HREDRAW | CS_VREDRAW;
        if (!RegisterClassEx(&wc))
        {
            std::cerr << "注册窗口类失败! 错误码: " << GetLastError() << std::endl;
            DeleteObject(hScreenBitmap);
            return false;
        }

        // 准备窗口参数
        void *params[7] = {&startX, &startY, &endX, &endY, hScreenBitmap, &screenWidth, &screenHeight};
        HWND hwnd = CreateWindowEx(
            WS_EX_TOPMOST | WS_EX_TOOLWINDOW, // 最顶层且无任务栏图标
            "PointSelectionClass",
            "选择录制区域",
            WS_POPUP,
            0, 0, screenWidth, screenHeight,
            NULL, NULL, GetModuleHandle(NULL), params);
        if (!hwnd)
        {
            std::cerr << "创建窗口失败! 错误码: " << GetLastError() << std::endl;
            UnregisterClass("PointSelectionClass", GetModuleHandle(NULL));
            DeleteObject(hScreenBitmap);
            return false;
        }

        // 显示窗口
        ShowWindow(hwnd, SW_SHOW);
        UpdateWindow(hwnd);

        // 消息循环
        MSG msg;
        int result = 0;
        while (GetMessage(&msg, NULL, 0, 0))
        {
            if (msg.message == WM_QUIT)
            {
                result = (int)msg.wParam;
                break;
            }
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }

        // 清理资源
        DeleteObject(hScreenBitmap);
        UnregisterClass("PointSelectionClass", GetModuleHandle(NULL));

        // 无论结果如何，先打印当前选中的坐标
        std::string coords = "(" + std::to_string(startX) + "," + std::to_string(startY) +
                             "," + std::to_string(endX) + "," + std::to_string(endY) + ")";
        std::cout << "当前选中坐标: " << coords << std::endl;

        // 验证选择结果
        if (result == 1)
        {
            // 额外验证坐标有效性
            if (startX < endX && startY < endY)
            {
                std::cout << "已选择区域: (" << startX << "," << startY << "," << endX << "," << endY << ")" << std::endl;
                return true;
            }
            else
            {
                std::cerr << "错误: 选择的区域坐标无效" << std::endl;
                return false;
            }
        }
        else
        {
            std::cout << "区域选择已取消" << std::endl;
            return false;
        }
    }

    bool captureScreen(int x, int y, int width, int height, std::vector<uint8_t> &rgbaData) override
    {
        if (width <= 0 || height <= 0)
        {
            std::cerr << "无效的捕获区域尺寸!" << std::endl;
            return false;
        }

        // 获取屏幕DC
        HDC hdcScreen = GetDC(NULL);
        if (!hdcScreen)
        {
            std::cerr << "获取屏幕DC失败!" << std::endl;
            return false;
        }

        // 创建兼容DC和位图
        HDC hdcMemDC = CreateCompatibleDC(hdcScreen);
        HBITMAP hBitmap = CreateCompatibleBitmap(hdcScreen, width, height);
        if (!hBitmap)
        {
            std::cerr << "创建位图失败!" << std::endl;
            ReleaseDC(NULL, hdcScreen);
            DeleteDC(hdcMemDC);
            return false;
        }

        // 选择位图
        HBITMAP hOldBitmap = (HBITMAP)SelectObject(hdcMemDC, hBitmap);

        // 复制屏幕内容到位图
        BitBlt(hdcMemDC, 0, 0, width, height, hdcScreen, x, y, SRCCOPY);

        // 获取位图信息
        BITMAPINFO bmi = {0};
        bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
        bmi.bmiHeader.biWidth = width;
        bmi.bmiHeader.biHeight = height;
        bmi.bmiHeader.biPlanes = 1;
        bmi.bmiHeader.biBitCount = 32;
        bmi.bmiHeader.biCompression = BI_RGB;

        // 分配内存存储位图数据
        rgbaData.resize(width * height * 4);

        // 获取位图数据并翻转（解决上下倒置问题）
        GetDIBits(hdcMemDC, hBitmap, 0, height, rgbaData.data(), &bmi, DIB_RGB_COLORS);
        flipImageVertically(rgbaData, width, height);

        // 清理资源
        SelectObject(hdcMemDC, hOldBitmap);
        DeleteObject(hBitmap);
        DeleteDC(hdcMemDC);
        ReleaseDC(NULL, hdcScreen);

        return true;
    }
};

// 创建平台实例
Platform *Platform::create()
{
    return new WindowsPlatform();
}

// 区域坐标结构
// 区域坐标结构
struct Region
{
    int startX = 0;
    int startY = 0;
    int endX = 0;
    int endY = 0;

    bool isValid() const
    {
        return startX < endX && startY < endY &&
               startX >= 0 && startY >= 0 &&
               endX > 0 && endY > 0;
    }

    // 从字符串解析区域坐标，格式: (startx,starty,endx,endy)
    // 支持逗号前后有任意空格，例如 (100,  200 , 300 , 400)
    bool parse(const std::string &str)
    {
        if (str.empty() || str[0] != '(' || str.back() != ')')
            return false;

        // 提取括号内的内容
        std::string coords = str.substr(1, str.size() - 2);
        std::vector<std::string> parts;
        size_t pos = 0;
        size_t next;

        // 分割字符串，忽略逗号前后的空格
        while (pos < coords.size())
        {
            // 跳过当前位置的空格
            while (pos < coords.size() && isspace(coords[pos]))
                pos++;

            if (pos >= coords.size())
                break;

            // 找到下一个逗号
            next = coords.find(',', pos);
            if (next == std::string::npos)
                next = coords.size();

            // 提取当前部分并去除前后空格
            std::string part = coords.substr(pos, next - pos);
            size_t start = 0, end = part.size();
            while (start < end && isspace(part[start]))
                start++;
            while (end > start && isspace(part[end - 1]))
                end--;
            part = part.substr(start, end - start);

            if (!part.empty())
                parts.push_back(part);

            // 移动到下一个位置
            pos = next + 1;
        }

        // 必须正好提取到4个数值
        if (parts.size() != 4)
            return false;

        try
        {
            startX = std::stoi(parts[0]);
            startY = std::stoi(parts[1]);
            endX = std::stoi(parts[2]);
            endY = std::stoi(parts[3]);
        }
        catch (...)
        {
            // 转换失败（非整数）
            return false;
        }

        return isValid();
    }

    // 转换为字符串表示
    std::string toString() const
    {
        return "(" + std::to_string(startX) + "," + std::to_string(startY) + "," +
               std::to_string(endX) + "," + std::to_string(endY) + ")";
    }
};

// 配置结构
struct Config
{
    bool fullscreen = true;
    int fps = 10;
    int duration = 3; // 秒
    std::string output = "recording.gif";
    int delay = 0;
    bool useSelectedRegion = false;
    Region region;
    bool isRegionSelected = false; // 标记是否通过-s选择了区域
};

// 显示使用帮助
void showUsage()
{
    std::cout << "GIF屏幕录制工具 - 使用msf_gif库实现" << std::endl;
    std::cout << "----------------------------------------" << std::endl;
    std::cout << "用法: gif-rec [选项]" << std::endl;
    std::cout << std::endl;
    std::cout << "选项:" << std::endl;
    std::cout << "  -h, --help            显示此帮助信息" << std::endl;
    std::cout << "  -f, --fps <数值>      设置录制帧率 (默认: 10)" << std::endl;
    std::cout << "  -d, --duration <秒>   设置录制时长 (默认: 3秒)" << std::endl;
    std::cout << "  -o, --output <文件>   设置输出文件名 (默认: recording.gif)" << std::endl;
    std::cout << "  -s, --select          使用鼠标选择录制区域" << std::endl;
    std::cout << "  -ss, --screen-region  指定录制区域坐标，格式: (startx,starty,endx,endy)" << std::endl;
    std::cout << "  --delay <秒>          开始录制前的延迟时间 (默认: 0)" << std::endl;
    std::cout << std::endl;
    std::cout << "示例:=========================================================================" << std::endl;
    std::cout << "  gif-rec.exe -f 15 -d 5 -o animation.gif              以15fps录制5秒的全屏GIF" << std::endl;
    std::cout << "  gif-rec.exe -f 20 -d 10                              鼠标选择区域，以20fps录制10秒" << std::endl;
    std::cout << "  gif-rec.exe -ss (100,100,800,600)                    录制指定区域5秒" << std::endl;
    std::cout << "  gif-rec.exe -s                                       仅选择区域，不录制，显示坐标(选点，todo)" << std::endl;
    std::cout << "  gif-rec.exe --delay 10                               延迟10s录制" << std::endl;
}

// 解析命令行参数
bool parseCommandLine(int argc, char *argv[], Config &config)
{
    for (int i = 1; i < argc; ++i)
    {
        std::string arg = argv[i];

        if (arg == "-h" || arg == "--help")
        {
            showUsage();
            return false;
        }
        else if (arg == "-f" || arg == "--fps")
        {
            if (i + 1 < argc)
            {
                config.fps = std::stoi(argv[++i]);
                if (config.fps <= 0 || config.fps > 60)
                {
                    std::cerr << "错误: FPS必须在1-60之间" << std::endl;
                    return false;
                }
            }
            else
            {
                std::cerr << "错误: " << arg << "选项需要一个参数" << std::endl;
                return false;
            }
        }
        else if (arg == "-d" || arg == "--duration")
        {
            if (i + 1 < argc)
            {
                config.duration = std::stoi(argv[++i]);
                if (config.duration <= 0)
                {
                    std::cerr << "错误: 录制时长必须大于0" << std::endl;
                    return false;
                }
            }
            else
            {
                std::cerr << "错误: " << arg << "选项需要一个参数" << std::endl;
                return false;
            }
        }
        else if (arg == "-o" || arg == "--output")
        {
            if (i + 1 < argc)
            {
                config.output = argv[++i];
            }
            else
            {
                std::cerr << "错误: " << arg << "选项需要一个参数" << std::endl;
                return false;
            }
        }
        else if (arg == "-s" || arg == "--select")
        {
            config.useSelectedRegion = true;
            config.fullscreen = false;
        }
        else if (arg == "-ss" || arg == "--screen-region")
        {
             if (i + 1 < argc)
            {
                std::string regionArg = argv[++i];
                std::string processedArg = regionArg;
                
                // 预处理区域参数，确保格式正确
                // 如果参数以(开头但不以)结尾，尝试从后续参数中查找)
                if (regionArg[0] == '(' && regionArg.back() != ')') {
                    std::string combinedArg = regionArg;
                    for (int j = i + 1; j < argc; ++j) {
                        combinedArg += " " + std::string(argv[j]);
                        if (argv[j][strlen(argv[j]) - 1] == ')') {
                            i = j; // 更新索引以跳过已处理的参数
                            processedArg = combinedArg;
                            break;
                        }
                    }
                }
                
                // 如果参数不以(开头和)结尾，添加它们
                if (processedArg[0] != '(') {
                    processedArg = "(" + processedArg;
                }
                if (processedArg.back() != ')') {
                    processedArg += ")";
                }
                
                // 解析处理后的参数
                if (!config.region.parse(processedArg))
                {
                    std::cerr << "错误: 无效的区域坐标格式。请使用格式: (startx,starty,endx,endy)" << std::endl;
                    return false;
                }
                config.useSelectedRegion = true;
                config.fullscreen = false;
            }
            else
            {
                std::cerr << "错误: " << arg << "选项需要一个参数" << std::endl;
                return false;
            }
        }
        else if (arg == "--delay")
        {
            if (i + 1 < argc)
            {
                config.delay = std::stoi(argv[++i]);
                if (config.delay < 0)
                {
                    std::cerr << "错误: 延迟时间不能为负数" << std::endl;
                    return false;
                }
            }
            else
            {
                std::cerr << "错误: " << arg << "选项需要一个参数" << std::endl;
                return false;
            }
        }
        else
        {
            std::cerr << "错误: 未知选项 " << arg << std::endl;
            showUsage();
            return false;
        }
    }

    return true;
}

// 录制GIF
bool recordGif(const Config &config, Platform *platform)
{
    int x = 0, y = 0, width = 0, height = 0;
    Region region = config.region;

    // 获取屏幕尺寸或选择区域
    if (config.fullscreen)
    {
        if (!platform->getScreenSize(width, height))
        {
            std::cerr << "错误: 无法获取屏幕尺寸" << std::endl;
            return false;
        }
        std::cout << "录制全屏: " << width << "x" << height << std::endl;
    }
    else if (config.useSelectedRegion)
    {
        if (config.isRegionSelected || region.isValid())
        {
            // 使用命令行指定的坐标或已选择的区域
            x = region.startX;
            y = region.startY;
            width = region.endX - region.startX;
            height = region.endY - region.startY;

            if (!region.isValid())
            {
                std::cerr << "错误: 区域坐标无效" << std::endl;
                return false;
            }

            std::cout << "使用录制区域: " << region.toString() << std::endl;
        }
        else
        {
            // 鼠标选择区域
            std::cout << "等待用户选择录制区域..." << std::endl;
            if (!platform->selectRegionByPoints(region.startX, region.startY, region.endX, region.endY))
            {
                std::cerr << "错误: 用户取消选择或选择失败" << std::endl;
                return false;
            }

            // 计算区域坐标
            x = region.startX;
            y = region.startY;
            width = region.endX - region.startX;
            height = region.endY - region.startY;

            // 验证区域尺寸
            if (width <= 0 || height <= 0)
            {
                std::cerr << "错误: 选择的区域尺寸无效" << std::endl;
                return false;
            }

            std::cout << "成功选择区域: " << region.toString() << std::endl;

            // 如果用户没有指定持续时间，则仅显示坐标并退出
            if (config.duration <= 0)
            {
                std::cout << "区域选择完成。如需录制，请使用 -ss " << region.toString() << " 参数" << std::endl;
                return true;
            }
        }
    }
    else
    {
        std::cerr << "错误: 必须指定全屏录制或选择录制区域" << std::endl;
        return false;
    }

    // 如果只选择区域而不录制，直接返回
    if (config.duration <= 0)
    {
        std::cout << "区域选择完成。坐标: " << region.toString() << std::endl;
        std::cout << "如需录制，请使用 -ss " << region.toString() << " 参数" << std::endl;
        return true;
    }

    // 延迟开始录制
    if (config.delay > 0)
    {
        std::cout << "录制将在 " << config.delay << " 秒后开始..." << std::endl;
        for (int i = config.delay; i > 0; --i)
        {
            std::cout << "\r倒计时: " << i << " 秒" << std::flush;
            std::this_thread::sleep_for(std::chrono::seconds(1));
        }
        std::cout << std::endl;
    }

    // 显示录制信息
    std::cout << "开始录制GIF..." << std::endl;
    std::cout << "区域: " << x << ", " << y << " 尺寸: " << width << "x" << height << std::endl;
    std::cout << "帧率: " << config.fps << "fps  时长: " << config.duration << "秒" << std::endl;
    std::cout << "输出文件: " << config.output << std::endl;

    // 初始化GIF编码器
    MsfGifState gifState = {};
    msf_gif_begin(&gifState, width, height);

    // 计算总帧数和每帧延迟(百分之一秒)
    int totalFrames = config.fps * config.duration;
    int centisecondsPerFrame = 100 / config.fps; // 每帧延迟(百分之一秒)

    std::vector<uint8_t> frameData;

    // 初始化通用控件
    INITCOMMONCONTROLSEX icc;
    icc.dwSize = sizeof(icc);
    icc.dwICC = ICC_PROGRESS_CLASS;
    InitCommonControlsEx(&icc);

    // 创建录制进度窗口
    HWND progressWnd = CreateWindowEx(
        0, "Static", "正在录制...",
        WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU,
        CW_USEDEFAULT, CW_USEDEFAULT, 300, 120,
        NULL, NULL, GetModuleHandle(NULL), NULL);

    if (progressWnd)
    {
        // 创建进度条控件
        HWND progressBar = CreateWindowEx(
            0, PROGRESS_CLASS, "",
            WS_CHILD | WS_VISIBLE,
            10, 40, 280, 20,
            progressWnd, (HMENU)1, GetModuleHandle(NULL), NULL);

        // 设置进度条范围
        SendMessage(progressBar, PBM_SETRANGE, 0, MAKELPARAM(0, totalFrames));

        // 显示窗口
        ShowWindow(progressWnd, SW_SHOW);
        UpdateWindow(progressWnd);

        // 录制主循环
        for (int frame = 0; frame < totalFrames; ++frame)
        {
            auto startTime = std::chrono::high_resolution_clock::now();

            // 捕获当前帧
            if (!platform->captureScreen(x, y, width, height, frameData))
            {
                std::cerr << "错误: 无法捕获屏幕" << std::endl;
                msf_gif_end(&gifState);
                DestroyWindow(progressWnd);
                return false;
            }

            // 添加帧到GIF
            msf_gif_frame(&gifState, frameData.data(), centisecondsPerFrame, 8, width * 4);

            // 更新进度条
            SendMessage(progressBar, PBM_SETPOS, frame + 1, 0);

            // 更新窗口标题显示进度
            char title[100];
            sprintf_s(title, "正在录制... %d/%d 帧", frame + 1, totalFrames);
            SetWindowText(progressWnd, title);

            // 处理窗口消息
            MSG msg;
            while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
            {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }

            // 显示进度
            std::cout << "\r录制进度: " << (frame + 1) << "/" << totalFrames << " 帧" << std::flush;

            // 控制帧率
            auto endTime = std::chrono::high_resolution_clock::now();
            auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime).count();

            if (elapsed < (1000 / config.fps))
            {
                std::this_thread::sleep_for(std::chrono::milliseconds((1000 / config.fps) - elapsed));
            }
        }

        // 关闭进度窗口
        DestroyWindow(progressWnd);
    }
    else
    {
        // 如果窗口创建失败，使用控制台进度
        for (int frame = 0; frame < totalFrames; ++frame)
        {
            auto startTime = std::chrono::high_resolution_clock::now();

            // 捕获当前帧
            if (!platform->captureScreen(x, y, width, height, frameData))
            {
                std::cerr << "错误: 无法捕获屏幕" << std::endl;
                msf_gif_end(&gifState);
                return false;
            }

            // 添加帧到GIF
            msf_gif_frame(&gifState, frameData.data(), centisecondsPerFrame, 8, width * 4);

            // 显示进度
            std::cout << "\r录制进度: " << (frame + 1) << "/" << totalFrames << " 帧" << std::flush;

            // 控制帧率
            auto endTime = std::chrono::high_resolution_clock::now();
            auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime).count();

            if (elapsed < (1000 / config.fps))
            {
                std::this_thread::sleep_for(std::chrono::milliseconds((1000 / config.fps) - elapsed));
            }
        }
    }

    std::cout << std::endl;

    // 结束GIF生成
    MsfGifResult result = msf_gif_end(&gifState);

    // 保存GIF文件
    if (result.data)
    {
        FILE *fp = fopen(config.output.c_str(), "wb");
        if (fp)
        {
            fwrite(result.data, result.dataSize, 1, fp);
            fclose(fp);

            std::cout << "GIF录制完成! 文件大小: " << result.dataSize << " 字节" << std::endl;
        }
        else
        {
            std::cerr << "错误: 无法打开输出文件" << std::endl;
            msf_gif_free(result);
            return false;
        }
    }
    else
    {
        std::cerr << "错误: 生成GIF失败" << std::endl;
        return false;
    }

    // 释放资源
    msf_gif_free(result);

    return true;
}

int main(int argc, char *argv[])
{
    // 启用 DPI 感知
    SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);

    // 注册窗口类用于进度窗口
    WNDCLASSEX wc = {0};
    wc.cbSize = sizeof(WNDCLASSEX);
    wc.lpfnWndProc = DefWindowProc;
    wc.hInstance = GetModuleHandle(NULL);
    wc.lpszClassName = "ProgressWindowClass";
    RegisterClassEx(&wc);

    // 创建平台实例
    std::unique_ptr<Platform> platform(Platform::create());
    if (!platform)
    {
        std::cerr << "错误: 不支持当前平台" << std::endl;
        return 1;
    }

    Config config;

    // 解析命令行参数
    if (!parseCommandLine(argc, argv, config))
    {
        return 1;
    }

    // 处理 -s 选项：如果使用了 -s 但没有指定 -d，则只选择区域不录制
    if (config.useSelectedRegion && !config.region.isValid())
    {
        if (config.duration == 3)
        {                        // 默认值3秒，表示用户没有指定持续时间
            config.duration = 0; // 表示只选择区域
        }

        // 鼠标选择区域
        std::cout << "等待用户选择录制区域..." << std::endl;
        if (!platform->selectRegionByPoints(config.region.startX, config.region.startY,
                                            config.region.endX, config.region.endY))
        {
            std::cerr << "错误: 用户取消选择或选择失败" << std::endl;
            return 1;
        }

        config.isRegionSelected = true;
        std::cout << "已选择区域: " << config.region.toString() << std::endl;

        // 如果只需要选择区域（没有指定持续时间），输出提示并退出
        if (config.duration <= 0)
        {
            std::cout << "区域选择完成。如需录制，请使用 -ss " << config.region.toString() << " 参数" << std::endl;
            return 0;
        }
    }

    // 录制GIF
    bool result = recordGif(config, platform.get());

    // 清理
    UnregisterClass("ProgressWindowClass", GetModuleHandle(NULL));

    return result ? 0 : 1;
}